package com.itheima.health.task;

import com.alibaba.fastjson.JSON;
import com.itheima.health.dto.SetmealCount;
import com.itheima.health.dto.StatisticsMemberDTO;
import com.itheima.health.dto.StatisticsOrderDTO;
import com.itheima.health.mapper.MemberMapper;
import com.itheima.health.mapper.OrderMapper;
import com.itheima.health.mapper.ReportMapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Component
public class ReportJob {

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private StringRedisTemplate srt;

    @XxlJob("getMemberReport")
    public void getMemberReport(){
        //查询前一日数据
        LocalDate date = LocalDate.now().minusDays(1);
        //新用户数
        Integer newUser = getMemberCount(date, date);
        newUser = newUser == null? 0 : newUser;
        //总用户数量
        Integer totalUser = getMemberCount(null, date);
        totalUser = totalUser == null? 0 : totalUser;
        //记录到统计表
        StatisticsMemberDTO dto = new StatisticsMemberDTO(date, newUser, totalUser);

        //清理旧数据，存入新数据
        reportMapper.deleteMemberStatisticsByDate(date);
        reportMapper.insertMemberStatistics(dto);

        //封装月份
        getNearYearMemberStatistics(LocalDate.now());
    }

    @XxlJob("getBusinessReportData")
    public void getBusinessReportData(){
        //查询前一日数据
        LocalDate date = LocalDate.now().minusDays(1);
        //预约数
        Integer appointmentCount = getOrderCount(date, date, "未到诊");
        appointmentCount = appointmentCount == null? 0 : appointmentCount;
        //就诊数
        Integer visitCount = getOrderCount(date, date, "已到诊");
        visitCount = visitCount == null? 0 : visitCount;
        //记录到统计表
        StatisticsOrderDTO dto1 = new StatisticsOrderDTO(date, appointmentCount, visitCount);
        //清理旧数据，存入新数据
        reportMapper.deleteOrderStatisticsByDate(date);
        reportMapper.insertOrderStatistics(dto1);
    }

    @XxlJob("getSetmealReport")
    public void getSetmealReport(){
        //套餐数
        List<SetmealCount> setmealCounts = orderMapper.selectSetmealAvaildCount();
        //套餐名
        ArrayList<String> setmealNames = new ArrayList<>();
        setmealCounts.stream().forEach(x -> setmealNames.add(x.getName()));

        HashOperations<String, Object, Object> opsForHash = srt.opsForHash();
        opsForHash.put("setmeal:statistics", "setmealNames", JSON.toJSONString(setmealNames));
        opsForHash.put("setmeal:statistics", "setmealCounts", JSON.toJSONString(setmealCounts));
    }

    @Transactional
    @XxlJob("temp")
    public void temp(){
        List<LocalDate> list = new LinkedList<>();
        for (int i = 0; i < 365; i++) {
            list.add(LocalDate.now().minusDays(i));
        }
        list.stream().forEach(x -> {
            //新增用户数量
            Integer newUser = getMemberCount(x, x);
            newUser = newUser == null? 0 : newUser;
            //总用户数量
            Integer totalUser = getMemberCount(null, x);
            totalUser = totalUser == null? 0 : totalUser;

            StatisticsMemberDTO dto = new StatisticsMemberDTO(x, newUser, totalUser);
            reportMapper.insertMemberStatistics(dto);

            //预约数
            Integer appointmentCount = getOrderCount(x, x, "未到诊");
            appointmentCount = appointmentCount == null? 0 : appointmentCount;

            //就诊数
            Integer visitCount = getOrderCount(x, x, "已到诊");
            visitCount = visitCount == null? 0 : visitCount;

            StatisticsOrderDTO dto1 = new StatisticsOrderDTO(x, appointmentCount, visitCount);
            reportMapper.insertOrderStatistics(dto1);
        });
    }

    public Integer getMemberCount(LocalDate begin, LocalDate end){
        Map map = new HashMap();
        map.put("begin",begin);
        map.put("end", end);
        return memberMapper.countByMap(map);
    }

    public Integer getOrderCount(LocalDate begin, LocalDate end, String status){
        Map map = new HashMap();
        map.put("begin",begin);
        map.put("end", end);
        map.put("status", status);
        return orderMapper.countByMap(map);
    }

    private void getNearYearMemberStatistics(LocalDate now){
        List<YearMonth> yearMonths = new ArrayList<>();
        // 获取当前时间起向前数的最近十二个月
        for (int i = 11; i >= 0; i--) {
            YearMonth yearMonth = YearMonth.from(now).minusMonths(i);
            yearMonths.add(yearMonth);
        }
        //  封装y轴数据
        //按月统计每月会员及增量
        ArrayList<Integer> memberCount = new ArrayList<>();
        Integer count = null;
        for (int i = 0; i <= 11; i++) {
            LocalDate endOfMonth = yearMonths.get(i).atEndOfMonth();
            //获取一年以前的会员总数
            count = reportMapper.getMemberTotalCountByMonth(endOfMonth);
            if (i == 11){
                //获取当前月的会员总数
                count = reportMapper.getMemberTotalCountByMonth(now.minusDays(1));
            }
            memberCount.add(count);
        }

        //封装x轴数据
        ArrayList<String> months = new ArrayList<>();
        for (YearMonth yearMonth : yearMonths) {
            String format = yearMonth.format(DateTimeFormatter.ofPattern("yyyy.MM"));
            months.add(format);
        }

        HashOperations<String, Object, Object> opsForHash = srt.opsForHash();
        srt.delete("member:year");
        opsForHash.put("member:year", "months", JSON.toJSONString(months));
        opsForHash.put("member:year", "memberCount", JSON.toJSONString(memberCount));
    }
}
